﻿using Common.Framework.Core.Common;
using MongoDB.Bson;
using MongoDB.Driver;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace Common.Framework.Core.MongoDB
{
    public interface IMongoBaseRepository<TDoc> where TDoc : BaseMongoEntity, new()
    {
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        long GenerateId();


        #region 增
        /// <summary>
        /// 
        /// </summary>
        /// <param name="doc"></param>
        /// <param name="options"></param>
        /// <returns></returns>
        Task<long> InsertAsync(TDoc doc, InsertOneOptions options = null);
        /// <summary>
        /// 
        /// </summary>
        /// <param name="bson"></param>
        /// <param name="options"></param>
        /// <returns></returns>
        Task<long> InsertAsync(BsonDocument bson, InsertOneOptions options = null);
        /// <summary>
        /// 
        /// </summary>
        /// <param name="docs"></param>
        /// <param name="options"></param>
        /// <returns></returns>
        Task<List<long>> BatchInsertAsync(IEnumerable<TDoc> docs, InsertManyOptions options = null);
        #endregion

        #region 改
        /// <summary>
        /// 
        /// </summary>
        /// <param name="doc"></param>
        /// <param name="filter"></param>
        /// <param name="options"></param>
        /// <returns></returns>
        Task<long> UpdateAsync(TDoc doc, Expression<Func<TDoc, bool>> filter = null, UpdateOptions options = null);
        /// <summary>
        /// 
        /// </summary>
        /// <param name="doc"></param>
        /// <param name="filter"></param>
        /// <param name="updateFields"></param>
        /// <param name="options"></param>
        /// <returns></returns>
        Task<long> UpdateAsync(TDoc doc, UpdateDefinition<TDoc> updateFields, Expression<Func<TDoc, bool>> filter = null, UpdateOptions options = null);
        #endregion

        #region 删
        /// <summary>
        /// 
        /// </summary>
        /// <param name="_id"></param>
        /// <returns></returns>
        Task<UpdateResult> SoftDeleteAsync(string _id, Expression<Func<TDoc, bool>> filter = null);
        /// <summary>
        /// 
        /// </summary>
        /// <param name="filter"></param>
        /// <param name="options"></param>
        /// <returns></returns>
        Task<DeleteResult> RealDeleteAsync(Expression<Func<TDoc, bool>> filter, DeleteOptions options = null);
        /// <summary>
        /// 
        /// </summary>
        /// <param name="filter"></param>
        /// <param name="options"></param>
        /// <returns></returns>
        Task<DeleteResult> RealBatchDeleteAsync(Expression<Func<TDoc, bool>> filter, DeleteOptions options = null);
        #endregion

        #region 查

        /// <summary>
        /// 
        /// </summary>
        /// <param name="filter"></param>
        /// <param name="options"></param>
        /// <returns></returns>
        Task<TDoc> QueryAsync(Expression<Func<TDoc, bool>> filter, FindOptions options = null);
        /// <summary>
        /// 
        /// </summary>
        /// <param name="filter"></param>
        /// <param name="options"></param>
        /// <returns></returns>
        Task<List<TDoc>> QueryListAsync(Expression<Func<TDoc, bool>> filter, FindOptions options = null);
        /// <summary>
        /// 
        /// </summary>
        /// <param name="filter"></param>
        /// <param name="orderByKey"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        Task<BasePageResponse<TDoc>> QueryPageListAsync(Expression<Func<TDoc, bool>> filter, Expression<Func<TDoc, object>> orderByKey = null, int pageIndex = 1, int pageSize = 10);
        /// <summary>
        /// 
        /// </summary>
        /// <param name="filter"></param>
        /// <param name="limitCount"></param>
        /// <returns></returns>
        Task<List<TDoc>> QueryTopList(Expression<Func<TDoc, bool>> filter, int limitCount);
        /// <summary>
        /// 
        /// </summary>
        /// <param name="filter"></param>
        /// <returns></returns>
        Task<long> CountAsync(Expression<Func<TDoc, bool>> filter);
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="filter"></param>
        /// <param name="distinctField"></param>
        /// <returns></returns>
        Task<List<TResult>> DistinctAsync<TResult>(Expression<Func<TDoc, bool>> filter = null, string distinctField = "");
        #endregion

        #region 其它操作
        /// <summary>
        /// 
        /// </summary>
        /// <param name="indexFields"></param>
        /// <param name="options"></param>
        /// <returns></returns>
        Task CreateCollectionAsync(string[] indexFields = null, CreateIndexOptions options = null);
        /// <summary>
        /// 
        /// </summary>
        /// <param name="collectionName"></param>
        /// <returns></returns>
        Task ClearCollectionAsync(string collectionName);
        /// <summary>
        /// 
        /// </summary>
        /// <param name="name"></param>
        /// <param name="settings"></param>
        /// <returns></returns>
        IMongoCollection<TDoc> GetCollection(string name, MongoCollectionSettings settings = null);
        #endregion
    }
}
